十二、编辑用户资料

您所在的位置:网站首页 黑马 头像 十二、编辑用户资料

十二、编辑用户资料

2024-07-17 05:03| 来源: 网络整理| 查看: 265

# 十二、编辑用户资料 # 1、创建组件并配置路由

1、创建 views/user-profile/index.vue

用户资料编辑页码 export default { name: "UserProfile" } 12345678910111213

2、将该页面配置到根路由

{ path: '/user/profile', name: 'user-profile', component: () => import('@/views/user-profile') } 12345

3、my/index.vue 给编辑资料按钮绑定跳转

编辑资料 12345# 2、页面布局 export default { name: 'UserProfile', components: {}, props: {}, data () { return {} }, computed: {}, watch: {}, created () {}, mounted () {}, methods: {} } .user-profile { .avatar-cell { .van-cell__value { display: flex; flex-direction: row-reverse; } .avatar { width: 60px; height: 60px; } } .van-popup{ background-color:#f5f7f9; } } 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061# 3、展示用户信息

思路:

找到数据接口 封装请求方法 请求获取数据 模板绑定

1、在 api/user.js 中添加封装数据接口

/** * 获取当前登录用户的个人资料 */ export const getUserProfile = target => { return request({ method: 'GET', url: '/v1_0/user/profile' }) } 123456789

2、在 views/user-profile/index.vue 组件中请求获取数据

import { getUserProfile } from '@/api/user' export default { name: 'UserProfile', components: { }, props: {}, data () { return { user: {} // 个人信息 } }, computed: {}, watch: {}, created () { this.loadUserProfile() }, mounted () {}, methods: { async loadUserProfile () { try { const { data } = await getUserProfile() this.user = data.data } catch (err) { this.$toast('数据获取失败') } } } } 12345678910111213141516171819202122232425262728293031

3、模板绑定

123456789101112131415161718192021222324252627282930# 4、修改昵称 # 4.1、准备弹出层

定义弹出层控制变量

data () { return { // 其他变量... isUpdateNameShow: false } }, 123456

绘制弹出层组件

昵称编辑修改 123456789

打开弹出层

123456 # 4.2、封装组件和布局

创建user-profile/components/update-name.vue组件

export default { name: 'UpdateName', components: {}, props: {}, data () { return { message:'' } }, computed: {}, watch: {}, created () {}, mounted () {}, methods: { } } .field-wrap { padding: 20px; } 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152

父组件 user-profile/index.vue 导入,注册,使用 且监听关闭事件

import UpdateName from './components/update-name' 1components: { UpdateName } 123 1234567891011 # 4.3、数据传递

父组件 传递用户昵称用于显示,且将来子组件内部会更新这个昵称,故而可使用v-model

  

12345678910111213

子组件定义props接收

    

props: { // 接收用户昵称 value: { type: String, required: true } } 1234567

将接收到的数据赋给data变量(如果直接绑定给输入框则违法了修改props的原则)

 

data () { return { message: this.value } }, 12345 # 4.4、发送请求

在api/user.js里面封装修改资料方法

/** * 更新用户资料 */ export const updateUserProfile = data => { return request({ method: 'PATCH', url: '/v1_0/user/profile', data }) } 1234567891011

确定按钮绑定事件

 

12345678

导入请求方法,发送请求

import { updateUserProfile } from '@/api/user' 1async onConfirm () { this.$toast.loading({ message: '保存中...', forbidClick: true, // 禁止背景点击 duration: 0 // 持续展示 }) try { const message = this.message if (!message.length) { this.$toast('昵称不能为空') return } await updateUserProfile({ name: message }) // 更新视图 this.$emit('input', message) // 关闭弹层 this.$emit('close') // 提示成功 this.$toast.success('更新成功') } catch (err) { this.$toast.fail('更新失败') } } 123456789101112131415161718192021222324252627282930 # 5、修改性别 # 5.1、准备弹出层

定义弹出层控制变量

data () { return { // 其他变量... isUpdateGenderShow: false } }, 123456

绘制弹出层组件

编辑性别 12345678

打开弹出层

123456 # 5.2、封装组件和布局

创建user-profile/components/update-gender.vue组件

export default { name: 'UpdateGender', components: {}, props: {}, data () { return { columns: ['男', '女'], localGender:null // 当前性别 } }, computed: {}, watch: {}, created () {}, mounted () {}, methods: { // 确定事件 onConfirm(){ }, // 选择器发生变化的时候 onPickerChange (picker, value, index) { this.localGender = index } } } 123456789101112131415161718192021222324252627282930313233343536373839404142434445

父组件 user-profile/index.vue 导入,注册,使用 且监听关闭事件

import UpdateGender from './components/update-gender' 1components: { UpdateGender } 123 12345678910 # 5.3、数据传递

父组件 传递用户昵称用于显示,且将来子组件内部会更新这个性别,故而可使用v-model

  

123456789101112

子组件定义props接收

    

props: { // 接收用户性别 value: { type: Number, required: true } } 1234567

将接收到的数据赋给data变量(如果直接绑定给输入框则违法了修改props的原则)

 

data () { return { columns: ['男', '女'], localGender: this.value } }, 123456 # 5.4、发送请求

在api/user.js里面封装修改资料方法(相同不用封装)

/** * 更新用户资料 */ export const updateUserProfile = data => { return request({ method: 'PATCH', url: '/v1_0/user/profile', data }) } 1234567891011

导入请求方法,发送请求

import { updateUserProfile } from '@/api/user' 1async onConfirm () { this.$toast.loading({ message: '保存中...', forbidClick: true, // 禁止背景点击 duration: 0 // 持续展示 }) try { const localGender = this.localGender await updateUserProfile({ gender: localGender }) // 更新视图 this.$emit('input', localGender) // 关闭弹层 this.$emit('close') // 提示成功 this.$toast.success('更新成功') } catch (err) { this.$toast.fail('更新失败') } } 1234567891011121314151617181920212223242526

WARNING

目前性别修改后台接口存在问题,无论如何修改,性别依然是女

# 6、修改生日 # 6.1、准备弹出层

定义弹出层控制变量

data () { return { // 其他变量... isUpdateBirthdayShow: false } }, 123456

绘制弹出层组件

编辑生日 12345678

打开弹出层

123456 # 6.2、封装组件和布局

创建user-profile/components/update-birthday.vue组件

export default { name: 'UpdateGender', components: {}, props: {}, data () { return { minDate: new Date(1970, 0, 1), maxDate: new Date(), currentDate: new Date() } }, computed: {}, watch: {}, created () {}, mounted () {}, methods: { // 确定事件 onConfirm(){ } } } 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748

父组件 user-profile/index.vue 导入,注册,使用 且监听关闭事件

import UpdateBirthday from './components/update-birthday' 1components: { UpdateBirthday } 123 12345678910 # 6.3、数据传递

父组件 传递用户昵称用于显示,且将来子组件内部会更新这个生日,故而可使用v-model

  

123456789101112

子组件定义props接收

    

props: { // 接收用户生日 value: { type: String, required: true } } 1234567

将接收到的数据赋给data变量(如果直接绑定给输入框则违法了修改props的原则)

 

data () { return { minDate: new Date(1970, 0, 1), maxDate: new Date(), currentDate: new Date(this.value) } }, 1234567 # 6.4、发送请求

在api/user.js里面封装修改资料方法(相同不用封装)

/** * 更新用户资料 */ export const updateUserProfile = data => { return request({ method: 'PATCH', url: '/v1_0/user/profile', data }) } 1234567891011

导入请求方法,发送请求

import { updateUserProfile } from '@/api/user' import dayjs from 'dayjs' 12 async onConfirm () { this.$toast.loading({ message: '保存中...', forbidClick: true, // 禁止背景点击 duration: 0 // 持续展示 }) try { const currentDate = dayjs(this.currentDate).format('YYYY-MM-DD') await updateUserProfile({ birthday: currentDate }) // 更新视图 this.$emit('input', currentDate) // 关闭弹层 this.$emit('close') // 提示成功 this.$toast.success('更新成功') } catch (err) { this.$toast.fail('更新失败') } } 1234567891011121314151617181920212223242526 # 7、修改头像 # 7.1、图片预览思路

方式一:结合服务器的图片上传预览

方式二:纯客户端实现上传图片预览

// 获取文文件对象 const file = fileInput.files[0] // 设置图片的 src img.src = window.URL.createObjectURL(file) 12345

客户端上传预览示例:

DOCTYPE html> 客户端图片上传预览示例 .img-wrap { width: 200px; height: 200px; border: 1px solid #ccc; } img { max-width: 100%; } 客户端图片上传预览示例 const img = document.querySelector('#img') const file = document.querySelector('#file') function onFileChange() { // 得到 file-input 的文件对象 const fileObj = file.files[0] const data = window.URL.createObjectURL(fileObj) img.src = data } 1234567891011121314151617181920212223242526272829303132333435363738

接下来就是在项目中使用纯客户端的方式处理用户头像上传预览。

# 7.2、头像裁切思路

方案一:结合服务端的图片裁切上传流程

方案二:纯客户端的图片裁切上传流程

(opens new window) 在web应用程序中使用文件 (opens new window) 优秀插件: https://github.com/fengyuanchen/cropperjs # 7.3、实现图片预览功能 处理file-input

增加一个文件选择标签,让头像行点击触发文件选择器的点击事件

 

 

12345678910111213141516         onFileChange () { // 获取文件对象 const file = this.$refs.file.files[0] // 基于文章对象获取 blob 数据 const data = window.URL.createObjectURL(file) console.log(data) } 123456789功能处理

准备弹出层

编辑头像编辑头像编辑头像 123456789

定义存储头像预览数据变量和弹框控制变量

  

data () { return{ // 其他数据... isUpdatePhotoShow: false, img: null // 预览的图片 } } 1234567

打开弹框,赋值预览图片地址数据

        

onFileChange () { // 获取文件对象 const file = this.$refs.file.files[0] // 基于文章对象获取 blob 数据 this.img = window.URL.createObjectURL(file) // 展示预览图片弹出层 this.isUpdatePhotoShow = true // file-input 如果选了同一个文件不会触发 change 事件 // 解决办法就是每次使用完毕,把它的 value 清空 this.$refs.file.value = '' } 1234567891011121314

创建user-profile/components/update-photo.vue组件

取消 完成 export default { name: 'UpdatePhoto', components: {}, props: { // 预览图片地址信息 img: { type: [String, Object], required: true } }, data () { return {} }, computed: {}, watch: {}, created () {}, mounted () {}, methods: { // 确定事件 onConfirm(){ } } } .update-photo { background-color: #000; height: 100%; .toolbar { position: fixed; left: 0; right: 0; bottom: 0; display: flex; justify-content: space-between; .cancel, .confirm { width: 90px; height: 90px; font-size: 30px; display: flex; justify-content: center; align-items: center; color: #fff; } } } .img { display: block; max-width: 100%; } 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566

父组件 user-profile/index.vue 导入,注册,使用 且监听关闭事件

import UpdatePhoto from './components/update-photo' 1 components: { // 其他注册... UpdatePhoto }, 1234 12345678910111213# 7.4、实现图片裁剪上传 使用裁剪组件

安装cropperjs导入使用, 文档地址: https://github.com/fengyuanchen/cropperjs

npm i cropperjs 1

导入使用,初始化

import 'cropperjs/dist/cropper.css' import Cropper from 'cropperjs' 12data () { return { cropper: null // 裁剪器对象 } } mounted () { const image = this.$refs.img this.cropper = new Cropper(image, { viewMode: 1, dragMode: 'move', aspectRatio: 1, // autoCropArea: 1, cropBoxMovable: false, cropBoxResizable: false, background: false }) // 不能在这里调用 this.cropper.getCroppedCanvas() 方法!因为裁剪器还没初始化好! } 12345678910111213141516171819

注意:

要求被裁剪的img标签元素,必须有个块标签包裹! 必须在mounted里面调用,因为这里组件才挂载完成

获取裁剪结果信息

注意,不能在初始化后立即调用获取结果的方法,因为裁剪器初始化是一个异步过程,这里可能存在没有初始化好的情况

onConfirm () { // 基于服务端的裁切使用 getData 方法获取裁切参数 // console.log(this.cropper.getData()) // 纯客户端的裁切使用 getCroppedCanvas 获取裁切的文件对象 this.cropper.getCroppedCanvas().toBlob(blob => { console.log(blob) // 裁剪后的结果信息 }) }, 123456789提交头像修改

api/user.js封装头像修改方法

/** * 更新用户照片资料 */ export const updateUserPhoto = data => { return request({ method: 'PATCH', url: '/v1_0/user/photo', data }) } 12345678910

页面中导入使用,提交头像资料

import { updateUserPhoto } from '@/api/user' 1async updateUserPhoto (blob) { this.$toast.loading({ message: '保存中...', forbidClick: true, // 禁止背景点击 duration: 0 // 持续展示 }) try { // 错误的用法 // 如果接口要求 Content-Type 是 application/json // 则传递普通 JavaScript 对象 // updateUserPhoto({ // photo: blob // }) // 如果接口要求 Content-Type 是 multipart/form-data // 则你必须传递 FormData 对象 const formData = new FormData() formData.append('photo', blob) const { data } = await updateUserPhoto(formData) // 关闭弹出层 this.$emit('close') // 更新视图 this.$emit('update-photo', data.data.photo) // 提示成功 this.$toast.success('更新成功') } catch (err) { this.$toast.fail('更新失败') } } 123456789101112131415161718192021222324252627282930313233

 

onConfirm () { // 基于服务端的裁切使用 getData 方法获取裁切参数 // console.log(this.cropper.getData()) // 纯客户端的裁切使用 getCroppedCanvas 获取裁切的文件对象 this.cropper.getCroppedCanvas().toBlob(blob => { this.updateUserPhoto(blob) }) } 123456789

父组件里面监听头像更新事件,修改头像信息

 

1234567891011121314


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3